package graphdao

import (
	"power/core/dao/table"
	"power/core/localwrap"
	"power/core/service/common"

	"github.com/RocksonZeta/wrap/redised"
	"github.com/RocksonZeta/wrap/utils/sutil"
	"github.com/RocksonZeta/wrap/utils/timeutil"
)

const tableProjectUser = "ProjectUser"
const tableProjectUserId = "Id"

var logProjectUsers = localwrap.GetLogger().Fork("power/core/dao/graphdao", "ProjectUsers")

//ProjectUsers
type ProjectUsers struct {
	*redised.RedisedMysql
}

type ProjectUsersQueryParam struct {
	common.Page
	OrderBys common.OrderBys
	Name     string
	Uid      int
}

//Query 根据条件查询
func (s ProjectUsers) Query(param ProjectUsersQueryParam) ([]table.ProjectUser, int64) {
	logProjectUsers.Debug().Func("Query").Interface("param", param).Send()
	wsql := " from ProjectUser pu left join Project p on pu.projectId=p.id where 1=1"
	if param.Uid > 0 {
		wsql += " and pu.uid=:Uid"
	}
	if param.Name != "" {
		param.Name = "%" + param.Name + "%"
		wsql += " and p.name like :Name"
	}
	ssql := "select *" + wsql + param.OrderBys.Sql(" order by pu.ct desc") + param.Limit()
	csql := "select count(*)" + wsql
	var r []table.ProjectUser
	s.Mysql.Select(&r, ssql, param)
	return r, s.Mysql.SelectInt(csql, param)
}

func (s ProjectUsers) Get(id int) table.ProjectUser {
	logProjectUsers.Debug().Func("Get").Int("id", id).Send()
	var r table.ProjectUser
	s.RedisedMysql.Get(&r, tableProjectUser, tableProjectUserId, id)
	return r
}

func (s ProjectUsers) List(ids []int) []table.ProjectUser {
	logProjectUsers.Debug().Func("List").Ints("ids", ids).Send()
	var r []table.ProjectUser
	s.RedisedMysql.List(&r, tableProjectUser, tableProjectUserId, ids)
	return r
}
func (s ProjectUsers) ListAsMap(ids []int) map[int]table.ProjectUser {
	logProjectUsers.Debug().Func("ListAsMap").Ints("ids", ids).Send()
	l := s.List(ids)
	r := make(map[int]table.ProjectUser, len(l))
	for _, v := range l {
		r[v.Id] = v
	}
	return r
}

func (s ProjectUsers) Delete(id int) {
	logProjectUsers.Debug().Func("Delete").Int("id", id).Send()
	old := s.Get(id)
	s.Mysql.Delete(tableProjectUser, tableProjectUserId, id)
	s.ClearCache(old)
}

func (s ProjectUsers) ClearCache(old table.ProjectUser) {
	logProjectUsers.Debug().Func("ClearCache").Int("id", old.Id).Send()
	s.Redis.Del(s.KeyFn(tableProjectUser, old.Id))
	s.Redis.Del(s.KVFn(tableProjectUser, map[string]interface{}{"uid": old.Uid, "projectId": old.ProjectId}))
	s.Redis.Del(s.KVFn(tableProjectUser, map[string]interface{}{"projectId": old.ProjectId}))
	s.Redis.Del(s.KVFn(tableProjectUser, map[string]interface{}{"uid": old.Uid}))
}
func (s ProjectUsers) GetByUidProjectId(uid int, projectId int) table.ProjectUser {
	logProjectUsers.Debug().Func("GetByUidProjectId").Int("uid", uid).Int("projectId", projectId).Send()
	var r table.ProjectUser
	s.RedisedMysql.GetByKvs(&r, tableProjectUser, tableProjectUserId, map[string]interface{}{"uid": uid, "projectId": projectId})
	return r
}
func (s ProjectUsers) ListByProjectId(projectId int) []table.ProjectUser {
	logProjectUsers.Debug().Func("ListByProjectId").Int("projectId", projectId).Send()
	var r []table.ProjectUser
	s.RedisedMysql.ListByKvs(&r, tableProjectUser, tableProjectUserId, map[string]interface{}{"projectId": projectId})
	return r
}
func (s ProjectUsers) ListByUid(uid int) []table.ProjectUser {
	logProjectUsers.Debug().Func("ListByUid").Int("uid", uid).Send()
	var r []table.ProjectUser
	s.RedisedMysql.ListByKvs(&r, tableProjectUser, tableProjectUserId, map[string]interface{}{"uid": uid})
	return r
}

type ProjectUsersUpdateParam struct {
	Id   int
	Role int
}

func (s ProjectUsers) Update(param ProjectUsersUpdateParam) {
	logProjectUsers.Debug().Func("Update").Interface("param", param).Send()
	s.Mysql.Patch(tableProjectUser, tableProjectUserId, param)
	s.Redis.Del(s.KeyFn(tableProjectUser, param.Id))
	// s.ClearCache(s.Get(param.Id)) if no index updated
}

type ProjectUsersAddParam struct {
	Uid       int
	ProjectId int
	Role      int
}

func (s ProjectUsers) Add(param ProjectUsersAddParam) table.ProjectUser {
	logProjectUsers.Debug().Func("Add").Interface("param", param).Send()
	var t table.ProjectUser
	sutil.Copy(param, &t)
	t.Ct = timeutil.Now()
	s.Mysql.AddTable(t)
	s.Mysql.Insert(&t)
	s.ClearCache(t)
	return t
}
